<template>
  <a-modal
    :title="title"
    :width="800"
    :maskClosable="false"
    :visible="visible"
    :confirmLoading="confirmLoading"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <a-spin :spinning="confirmLoading">
      <a-form-model ref="form" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">
        <a-row>
          <a-col :span="12">
            <a-form-model-item
              :label="$t('common.name')"
              prop="attributeName"
              :rules="[
                {
                  validator: validator.attributeNameValidator,
                  trigger: 'change'
                },
                {
                  required: true,
                  message: $t('common.emptyErr', { name: $t('common.name').toLowerCase() }),
                  whitespace: true,
                  trigger: 'change'
                }
              ]"
            >
              <a-input :maxLength="155" v-model.trim="form.attributeName" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item
              :label="$t('common.type')"
              prop="attributeType"
              :rules="[
                {
                  validator: validator.attributeTypeValidator,
                  trigger: 'change'
                },
                {
                  required: true,
                  message: $t('common.emptyErr', { name: $t('common.type').toLowerCase() }),
                  whitespace: true,
                  trigger: 'change'
                }
              ]"
            >
              <a-select
                @change="
                  val => {
                    form.attributeType = val;
                  }
                "
                :value="form.attributeType"
              >
                <a-select-option v-for="key in Object.keys(ATTRIBUTE_TYPE_ENUM)" :key="key" :value="key">{{
                  $t(ATTRIBUTE_TYPE_ENUM[key])
                }}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="12">
            <a-form-model-item
              prop="attributeTag"
              :rules="[
                {
                  pattern: databaseCol,
                  message: '首位可以是字母以及下划线。首位之后可以是字母，数字以及下划线。下划线后不能接下划线',
                  trigger: 'change'
                },
                {
                  validator: validator.attributeTagValidator,
                  trigger: 'change'
                },
                {
                  required: true,
                  message: $t('common.emptyErr', { name: $t('technology.uda.propIdentity').toLowerCase() }),
                  whitespace: true,
                  trigger: 'change'
                }
              ]"
            >
              <span slot="label">
                {{ $t('technology.uda.propIdentity') }}
                <a-tooltip title="支持_、小写英文字母、数字且不能以数字开头" :overlayStyle="{ maxWidth: '100%' }">
                  <a-icon type="question-circle-o" />
                </a-tooltip>
              </span>
              <a-input :maxLength="155" v-model.trim="form.attributeTag" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item :label="$t('technology.uda.isUnique')" prop="beUnique">
              <a-select
                @change="
                  val => {
                    form.beUnique = val;
                  }
                "
                :value="form.beUnique"
              >
                <a-select-option :value="0">{{ $t('common.no') }}</a-select-option>
                <a-select-option :value="1">{{ $t('common.yes') }}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="12">
            <a-form-model-item :label="$t('technology.uda.nullable')" prop="attributeType">
              <a-select
                @change="
                  val => {
                    form.beNull = val;
                  }
                "
                :value="form.beNull"
              >
                <a-select-option :value="0">{{ $t('common.no') }}</a-select-option>
                <a-select-option :value="1">{{ $t('common.yes') }}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </a-spin>
  </a-modal>
</template>

<script>
import { asyncValidateMixin } from '@/utils/mixin';
import {
  postUdaModelExtension,
  putUdaModelExtension,
  getUdaModelExtensionUnique
} from '@/api/technology/Uda/UDA模型表内置字段及扩展字段';
import { databaseCol } from '@/utils/regExp';
import { ATTRIBUTE_TYPE_ENUM } from '@/utils/enum';
import cloneDeep from 'lodash/cloneDeep';

export default {
  name: 'ExtensionForm',
  mixins: [asyncValidateMixin],
  data() {
    return {
      title: this.$t('technology.uda.addAttribute'),
      databaseCol,
      labelCol: {
        sm: {
          span: 10
        }
      },
      wrapperCol: {
        sm: {
          span: 12
        }
      },
      visible: false,
      confirmLoading: false,
      ATTRIBUTE_TYPE_ENUM,
      form: {
        allowDelete: 0,
        attributeName: '',
        attributeTag: '',
        attributeType: '',
        beNull: 0,
        beUnique: 0,
        serialNum: 0,
        tableName: ''
      },
      oldForm: {
        attributeName: ''
      }
    };
  },
  mounted() {
    this.$_asyncValidateMixin_init([
      {
        fieldName: 'attributeName',
        caller: getUdaModelExtensionUnique,
        extraParams: () => ({
          id: this.form.id || 0,
          tableName: this.form.tableName
        })
      },
      {
        fieldName: 'attributeTag',
        caller: getUdaModelExtensionUnique,
        extraParams: () => ({
          id: this.form.id || 0,
          tableName: this.form.tableName
        })
      }
    ]);
  },
  methods: {
    open(tableName, record) {
      this.visible = true;
      if (record) {
        this.title = this.$t('technology.uda.editAttribute');
        this.oldForm = record;
        this.form = cloneDeep(record);
      } else {
        this.title = this.$t('technology.uda.addAttribute');
        this.form.tableName = tableName;
      }
    },
    handleSubmit() {
      if (!this.canSubmit) {
        return;
      }
      this.confirmLoading = true;
      const fieldNames = this.$_asyncValidateMixin_fieldsFilter({
        attributeName: '',
        attributeTag: '',
        attributeType: ''
      });
      const validatePromise = fieldNames.map(fieldName => {
        const p = new Promise((resolve, reject) => {
          this.$refs.form.validateField(fieldName, errorMessage => {
            if (!errorMessage) {
              resolve();
            } else {
              reject(errorMessage);
            }
          });
        });
        return p;
      });
      Promise.all(validatePromise)
        .then(() => {
          let api = null;
          if (this.form.id) {
            api = putUdaModelExtension;
            const changeFields = this.handleCompare();
            this.form.changeFields = changeFields;
          } else {
            api = postUdaModelExtension;
          }
          api(this.form)
            .then(res => {
              this.$message.success(this.$t(res.message));
              this.$emit('ok');
              this.handleCancel();
            })
            .finally(() => {
              this.confirmLoading = false;
            });
        })
        .catch(() => {
          this.confirmLoading = false;
        });
    },
    handleCompare() {
      const changeFields = [];
      Object.keys(this.oldForm).forEach(key => {
        if (this.oldForm[key] !== this.form[key]) {
          changeFields.push(key);
        }
      });
      return `,${changeFields.join()},`;
    },
    handleCancel() {
      this.visible = false;
      this.form = {
        allowDelete: 0,
        attributeName: '',
        attributeTag: '',
        attributeType: '',
        beNull: 0,
        beUnique: 0,
        serialNum: 0,
        tableName: ''
      };
      this.oldForm = {
        attributeName: ''
      };
      this.$refs.form.resetFields();
      this.$_asyncValidateMixin_resetFields();
    },
    handleChangeType(val) {
      this.$set(this.form, 'attributeType', val);
    }
  }
};
</script>
